package com.demo.sso.shiro;

import com.demo.sso.common.constant.Const;
import com.demo.sso.common.constant.ShiroSessionRedisConstant;
import com.demo.sso.enity.LoginUser;
import com.demo.sso.util.RedisUtil;
import com.demo.sso.util.ShiroSessionConvertUtil;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;

import java.io.Serializable;

/**
 * 这个类就是shiro用来创建、修改、删除session的地方。在创建、修改、删除的时候，其实都是对redis做操作
 *
 * @author fengjy
 * @date 2018-10-30 20:12
 */
public class ShiroRedisDao extends EnterpriseCacheSessionDAO {

    @Override
    protected Serializable doCreate(Session session) {
        Serializable sessionId = super.doCreate(session);
        byte [] key = (ShiroSessionRedisConstant.SHIROSESSION_REDIS_PREFIX+sessionId.toString()).getBytes();
        RedisUtil.setObject(ShiroSessionRedisConstant.SHIROSESSION_REDIS_DB, key,
                ShiroSessionConvertUtil.sessionToByte(session), ShiroSessionRedisConstant.SHIROSESSION_REDIS_EXTIRETIME);

        return sessionId;
    }


    @Override
    public Session readSession(Serializable sessionId) throws UnknownSessionException {
        return this.doReadSession(sessionId);
    }

    @Override
    protected Session doReadSession(Serializable sessionId) {
        Session session = null;
        byte [] key = (ShiroSessionRedisConstant.SHIROSESSION_REDIS_PREFIX+sessionId.toString()).getBytes();
        byte[] bytes = RedisUtil.getObject(ShiroSessionRedisConstant.SHIROSESSION_REDIS_DB, key,
                ShiroSessionRedisConstant.SHIROSESSION_REDIS_EXTIRETIME);
        if(bytes != null && bytes.length > 0){
            session = ShiroSessionConvertUtil.byteToSession(bytes);
        }
        return session;
    }

    @Override
    protected void doUpdate(Session session) {
        super.doUpdate(session);
        byte [] key = (ShiroSessionRedisConstant.SHIROSESSION_REDIS_PREFIX+session.getId().toString()).getBytes();
        RedisUtil.updateObject(ShiroSessionRedisConstant.SHIROSESSION_REDIS_DB, key,
                ShiroSessionConvertUtil.sessionToByte(session),ShiroSessionRedisConstant.SHIROSESSION_REDIS_EXTIRETIME);
        //也要更新token
        LoginUser user = (LoginUser)session.getAttribute(Const.SESSION_USER);
        if(null != user){
            RedisUtil.updateString(ShiroSessionRedisConstant.SHIROSESSION_REDIS_DB,
                    ShiroSessionRedisConstant.SSOTOKEN_REDIS_PREFIX+user.getUserId(),
                    ShiroSessionRedisConstant.SHIROSESSION_REDIS_EXTIRETIME);
        }
    }

    @Override
    protected void doDelete(Session session) {
        super.doDelete(session);
        RedisUtil.delString(ShiroSessionRedisConstant.SHIROSESSION_REDIS_DB,
                ShiroSessionRedisConstant.SHIROSESSION_REDIS_PREFIX+session.getId().toString());
        //也要删除token
        LoginUser user = (LoginUser)session.getAttribute(Const.SESSION_USER);
        if(null != user){
            RedisUtil.delString(ShiroSessionRedisConstant.SHIROSESSION_REDIS_DB,
                    ShiroSessionRedisConstant.SSOTOKEN_REDIS_PREFIX+user.getUserId());
        }
    }

}
